import { Request, Response, NextFunction } from 'express';
import dataSourceService from '@services/datasource.service';
import DataSource from '@/database/models/DataSource';
import { DataSourceConfig, DataSourceType, DataSourceStatus } from '@/types/datasource.types';
import logger from '@utils/logger';

/**
 * 数据源控制器
 */
class DataSourceController {
  /**
   * 获取所有数据源
   * GET /api/datasources
   */
  async getAllDataSources(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { type, status, enabled } = req.query;

      let query: any = {};

      if (type) query.type = type;
      if (status) query.status = status;
      if (enabled !== undefined) query.enabled = enabled === 'true';

      const dataSources = await DataSource.find(query).sort({ priority: 1 });

      res.status(200).json({
        success: true,
        data: dataSources,
        total: dataSources.length,
      });
    } catch (error) {
      logger.error('Failed to get data sources:', error as Error);
      next(error);
    }
  }

  /**
   * 获取单个数据源
   * GET /api/datasources/:id
   */
  async getDataSource(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;

      const dataSource = await DataSource.findById(id);

      if (!dataSource) {
        res.status(404).json({
          success: false,
          message: 'Data source not found',
        });
        return;
      }

      res.status(200).json({
        success: true,
        data: dataSource,
      });
    } catch (error) {
      logger.error(`Failed to get data source ${req.params.id}:`, error as Error);
      next(error);
    }
  }

  /**
   * 创建数据源
   * POST /api/datasources
   */
  async createDataSource(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const config: DataSourceConfig = {
        id: '', // MongoDB 会自动生成
        ...req.body,
        status: DataSourceStatus.INACTIVE,
        metadata: {
          createdBy: (req as any).user?.username || 'system',
          totalAlertsReceived: 0,
          errorCount: 0,
        },
      };

      // 保存到数据库
      const dataSource = new DataSource(config);
      await dataSource.save();

      // 添加到服务中
      const result = await dataSourceService.addDataSource({
        ...config,
        id: (dataSource._id as any).toString(),
      });

      if (!result.success) {
        // 如果添加失败，删除数据库记录
        await DataSource.findByIdAndDelete(dataSource._id);

        res.status(400).json({
          success: false,
          message: result.message,
        });
        return;
      }

      // 更新状态
      dataSource.status = DataSourceStatus.ACTIVE;
      await dataSource.save();

      res.status(201).json({
        success: true,
        data: dataSource,
        message: 'Data source created successfully',
      });
    } catch (error: any) {
      logger.error('Failed to create data source:', error);

      if (error.code === 11000) {
        res.status(400).json({
          success: false,
          message: 'A data source with this name already exists',
        });
        return;
      }

      next(error);
    }
  }

  /**
   * 更新数据源
   * PUT /api/datasources/:id
   */
  async updateDataSource(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const updates = req.body;

      const dataSource = await DataSource.findById(id);

      if (!dataSource) {
        res.status(404).json({
          success: false,
          message: 'Data source not found',
        });
        return;
      }

      // 更新数据库
      Object.assign(dataSource, updates);
      await dataSource.save();

      // 更新服务
      await dataSourceService.updateDataSource(id, updates);

      res.status(200).json({
        success: true,
        data: dataSource,
        message: 'Data source updated successfully',
      });
    } catch (error) {
      logger.error(`Failed to update data source ${req.params.id}:`, error as Error);
      next(error);
    }
  }

  /**
   * 删除数据源
   * DELETE /api/datasources/:id
   */
  async deleteDataSource(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;

      const dataSource = await DataSource.findById(id);

      if (!dataSource) {
        res.status(404).json({
          success: false,
          message: 'Data source not found',
        });
        return;
      }

      // 从服务中删除
      dataSourceService.deleteDataSource(id);

      // 从数据库删除
      await DataSource.findByIdAndDelete(id);

      res.status(200).json({
        success: true,
        message: 'Data source deleted successfully',
      });
    } catch (error) {
      logger.error(`Failed to delete data source ${req.params.id}:`, error as Error);
      next(error);
    }
  }

  /**
   * 测试数据源连接
   * POST /api/datasources/:id/test
   */
  async testDataSource(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;

      let config: DataSourceConfig;

      // 如果是新数据源（还没保存），从请求体获取配置
      if (id === 'new') {
        config = req.body;
      } else {
        const dataSource = await DataSource.findById(id);
        if (!dataSource) {
          res.status(404).json({
            success: false,
            message: 'Data source not found',
          });
          return;
        }
        config = dataSource.toObject() as any;
        config.id = id;
      }

      const result = await dataSourceService.testDataSource(config);

      res.status(200).json({
        success: result.success,
        message: result.message,
        details: result.details,
      });
    } catch (error) {
      logger.error('Failed to test data source:', error as Error);
      next(error);
    }
  }

  /**
   * 启用/禁用数据源
   * PATCH /api/datasources/:id/toggle
   */
  async toggleDataSource(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;

      const dataSource = await DataSource.findById(id);

      if (!dataSource) {
        res.status(404).json({
          success: false,
          message: 'Data source not found',
        });
        return;
      }

      dataSource.enabled = !dataSource.enabled;
      await dataSource.save();

      // 更新服务
      await dataSourceService.updateDataSource(id, { enabled: dataSource.enabled });

      res.status(200).json({
        success: true,
        data: dataSource,
        message: `Data source ${dataSource.enabled ? 'enabled' : 'disabled'} successfully`,
      });
    } catch (error) {
      logger.error(`Failed to toggle data source ${req.params.id}:`, error as Error);
      next(error);
    }
  }

  /**
   * 获取数据源统计信息
   * GET /api/datasources/:id/stats
   */
  async getDataSourceStats(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;

      const dataSource = await DataSource.findById(id);

      if (!dataSource) {
        res.status(404).json({
          success: false,
          message: 'Data source not found',
        });
        return;
      }

      const stats = dataSourceService.getDataSourceStats(id);

      res.status(200).json({
        success: true,
        data: stats,
      });
    } catch (error) {
      logger.error(`Failed to get stats for data source ${req.params.id}:`, error as Error);
      next(error);
    }
  }

  /**
   * 从指定数据源获取告警
   * GET /api/datasources/:id/alerts
   */
  async fetchAlertsFromSource(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const { startTime, endTime } = req.query;

      const options: any = {};

      if (startTime) options.startTime = new Date(startTime as string);
      if (endTime) options.endTime = new Date(endTime as string);

      const alerts = await dataSourceService.fetchAlertsFromSource(id, options);

      res.status(200).json({
        success: true,
        data: alerts,
        total: alerts.length,
      });
    } catch (error: any) {
      logger.error(`Failed to fetch alerts from data source ${req.params.id}:`, error);
      res.status(500).json({
        success: false,
        message: error.message,
      });
    }
  }

  /**
   * 获取支持的数据源类型
   * GET /api/datasources/types
   */
  async getDataSourceTypes(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const types = [
        {
          type: DataSourceType.PROMETHEUS,
          name: 'Prometheus/Alertmanager',
          description: 'Monitor Kubernetes, cloud infrastructure, and applications',
          icon: 'prometheus',
          supported: true,
        },
        {
          type: DataSourceType.GRAFANA,
          name: 'Grafana',
          description: 'Analytics and monitoring platform',
          icon: 'grafana',
          supported: false,
        },
        {
          type: DataSourceType.ZABBIX,
          name: 'Zabbix',
          description: 'Enterprise-class monitoring solution',
          icon: 'zabbix',
          supported: false,
        },
        {
          type: DataSourceType.DATADOG,
          name: 'Datadog',
          description: 'Cloud monitoring service',
          icon: 'datadog',
          supported: false,
        },
        {
          type: DataSourceType.CLOUDWATCH,
          name: 'AWS CloudWatch',
          description: 'Amazon Web Services monitoring',
          icon: 'aws',
          supported: false,
        },
        {
          type: DataSourceType.CUSTOM_WEBHOOK,
          name: 'Custom Webhook',
          description: 'Receive alerts via HTTP webhook',
          icon: 'webhook',
          supported: false,
        },
      ];

      res.status(200).json({
        success: true,
        data: types,
      });
    } catch (error) {
      logger.error('Failed to get data source types:', error as Error);
      next(error);
    }
  }

  /**
   * 同步所有数据源
   * POST /api/datasources/sync
   */
  async syncAllDataSources(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const alerts = await dataSourceService.fetchAlertsFromAllSources();

      res.status(200).json({
        success: true,
        data: alerts,
        total: alerts.length,
        message: 'All data sources synced successfully',
      });
    } catch (error) {
      logger.error('Failed to sync all data sources:', error as Error);
      next(error);
    }
  }
}

export default new DataSourceController();
